﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using EasyCompany.MRU;

namespace Admx_Generator
{
    public partial class frmMain : Form
    {
        private System.Resources.ResourceManager resMan = new System.Resources.ResourceManager("Admx_Generator.Localization.LocalizedStrings", typeof(frmMain).Assembly);
        private AdmxProject _currentProject;
        private AdmlFile _currentLanguage = null;
        private List<AdmxProject> _openedProjects = new List<AdmxProject>();
        private MruList _mru = new MruList();
        private Bitmap _blankImage = new Bitmap(16, 16);

        public frmMain()
        {
            InitializeComponent();
            this.InitializeMRU();
            this.DisplayRecentelyOpenedFiles();
            this.SetupContextMenu();
        }

        #region (Internal Properties)

        /// <summary>
        /// Gets or Sets a reference to the currently selected project
        /// </summary>
        internal AdmxProject CurrentProject
        {
            get { return this._currentProject; }

            private set
            {
                this._currentProject = value;
                this.tlStripStatLabelCurrentProject.Text = this.GetLocalizedString("SelectedProject");
                this.tlStripStatLabelCurrentProject.Text += this._currentProject != null ? this._currentProject.ProjectName : this.GetLocalizedString("NoProjectSelected");
                this.DisplayProjectLanguages();
            }
        }

        /// <summary>
        /// Gets or Sets the currently selected language
        /// </summary>
        internal AdmlFile CurrentLanguage
        {
            get
            {
                return this._currentLanguage;
            }

            private set
            {
                this._currentLanguage = value;
                this.tlStripStatLabelCurrentLanguage.Text = this.GetLocalizedString("SelectedLanguage");
                this.tlStripStatLabelCurrentLanguage.Text += this._currentLanguage != null ? this._currentLanguage.ToString() : this.GetLocalizedString("None");
            }
        }

        /// <summary>
        /// Gets a list of all opened projects
        /// </summary>
        internal List<AdmxProject> OpenedProjects { get { return this._openedProjects; } }

        #endregion (Internal Properties)

        #region (Private Methods)

        /// <summary>
        /// Display all languages associated with the currently selected project
        /// </summary>
        private void DisplayProjectLanguages()
        {
            this.txtBxFallbackCulture.Text = String.Empty;
            this.lstBxAdml.Items.Clear();
            this.tlStripStatLabelCurrentLanguage.Text = this.GetLocalizedString("SelectedLanguage") + this.GetLocalizedString("None");

            if (this.CurrentProject != null)
            {
                AdmlFile fallbackCulture = null;
                if (this.CurrentProject.HasAdmx)
                {
                    fallbackCulture = this.CurrentProject.Admx.Resources.FallbackCulture;
                    this.txtBxFallbackCulture.Text = fallbackCulture.ToString();
                }
                foreach (AdmlFile language in this.CurrentProject.GetAdmlList())
                {
                    if (language != fallbackCulture)
                        this.lstBxAdml.Items.Add(language);
                }
                if (this.CurrentLanguage != null)
                {
                    this.tlStripStatLabelCurrentLanguage.Text = this.GetLocalizedString("SelectedLanguage") + this.CurrentLanguage.ToString();
                    if (this.lstBxAdml.Items.Contains(this.CurrentLanguage))
                        this.lstBxAdml.SelectedItem = this.CurrentLanguage;
                }
            }
        }

        /// <summary>
        /// Populate contextual menu with localized items
        /// </summary>
        private void SetupContextMenu()
        {
            // Project
            this.AddToolStripMenuItem(this.ctxMnuProject, "AddAdmx", Properties.Resources.Add24x24, "AddAdmxToolStripMenuItem");
            this.AddToolStripMenuItem(this.ctxMnuProject, "RenameProject", Properties.Resources.Rename16x16, "RenameProjectToolStripMenuItem");
            this.AddToolStripMenuItem(this.ctxMnuProject, "SaveProject", Properties.Resources.Save16x16, "SaveProjectToolStripMenuItem");
            this.AddToolStripMenuItem(this.ctxMnuProject, "CloseProject", Properties.Resources.Remove24x24, "CloseProjectToolStripMenuItem");

            // Admx
            this.AddToolStripMenuItem(this.ctxMnuAdmx, "RenameAdmx", Properties.Resources.Rename16x16, "RenameAdmxToolStripMenuItem");
            this.AddToolStripMenuItem(this.ctxMnuAdmx, "RemoveAdmx", Properties.Resources.Remove24x24, "RemoveAdmxToolStripMenuItem");


            // Category


            // Policy

        }

        /// <summary>
        /// Add a new menu item to the contextual menu.
        /// </summary>
        /// <param name="contextMenu">Contextual menu where to add the new item</param>
        /// <param name="unlocalizedText">A string to localized and add to the item as Text property</param>
        /// <param name="image">An image to add a left of the text of the item. Can be null.</param>
        /// <param name="name">Name of the new item. It will be used to recognize which itel have been clicked.</param>
        private void AddToolStripMenuItem(ContextMenuStrip contextMenu, string unlocalizedText, Image image, string name)
        {
            try
            {
                ToolStripMenuItem item = new ToolStripMenuItem(this.GetLocalizedString(unlocalizedText), image == null ? this._blankImage : image);
                item.Name = name;
                item.Click += ContextMenuItem_Click;
                contextMenu.Items.Add(item);
            }
            catch (Exception) { }
        }

        /// <summary>
        /// Create a new project based on the informations provided by the user.
        /// </summary>
        private void NewProject()
        {
            try
            {
#if(DEBUG)
                System.IO.DirectoryInfo projectFolder = new System.IO.DirectoryInfo(@"C:\Users\Courtel.MCSA\AppData\Local\Admx Generator\Projects\Admx Generator");
                if (projectFolder.Exists)
                { projectFolder.Delete(true); }

#endif
                FrmNewProject frmNewProject = new FrmNewProject(OpenedProjects);
                if (frmNewProject.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    this.Cursor = Cursors.WaitCursor;
                    AdmxProject newAdmxProject = new AdmxProject(frmNewProject.WorkingFolder, frmNewProject.ProjectName);
                    this.CurrentProject = newAdmxProject;

                    this.CurrentProject.HaveUnsavedModificationsChanged += CurrentProject_HasUnsavedModificationsChanged;
                    this.OpenedProjects.Add(newAdmxProject);
                    this.AddProjectToTreeview(newAdmxProject);

                    this.ribOrbCloseProject.Enabled = true;
                    this.ribOrbSave.Enabled = true;
                    this.ribOrbSaveAs.Enabled = true;
                }
            }
            catch (Exception ex) { MessageBox.Show(this.GetLocalizedString("AnErrorOccuredWhileCreatingNewProject") + "\r\n" + ex.Message); }

            this.Cursor = Cursors.Default;
        }

        /// <summary>
        /// Add the new project to the treeview
        /// </summary>
        /// <param name="newAdmxProject">AdmxProject to add to the treeview</param>
        private void AddProjectToTreeview(AdmxProject newAdmxProject)
        {
            TreeNode newNode = new TreeNode(newAdmxProject.ProjectName + (newAdmxProject.HaveUnsavedModifications ? "*" : String.Empty), 0, 0);
            newNode.Tag = new ProjectViewer(newAdmxProject);
            this.trvProjects.Nodes.Add(newNode);
            //newAdmxProject.OwnerNode = newNode;
            if (newAdmxProject.HasAdmx)
            { this.AddAdmxTotreeview(newAdmxProject.Admx); }
            this.trvProjects.SelectedNode = newNode;
        }

        /// <summary>
        /// Create a new treeview node with the AdmxFile object and add it to the Project node. 
        /// </summary>
        /// <param name="admxProject">AdmxProject that own the AdmxFile to add</param>
        private void AddAdmxTotreeview(AdmxFile admx)
        {
            TreeNode admxNode = new TreeNode(admx.Filename, 1, 1);
            admxNode.Tag = new AdmxViewer(admx);
            this.trvProjects.SelectedNode = admxNode;
        }

        private void AddAdmxToProject()
        {
            try
            {
                FrmAddAdmx frmAddAdmx = new FrmAddAdmx();
                if (frmAddAdmx.ShowDialog() == DialogResult.OK)
                {
                    AdmxFile newAdmx = null;
                    switch (frmAddAdmx.Method)
                    {
                        case FrmAddAdmx.AddingMethod.Import:
                            newAdmx = new AdmxFile(frmAddAdmx.FilenameToImport);
                            break;
                        case FrmAddAdmx.AddingMethod.Create:
                            newAdmx = new AdmxFile(frmAddAdmx.FilenameToCreate, frmAddAdmx.TargetedNamespace, frmAddAdmx.FallbackCulture);
                            break;
                        default:
                            MessageBox.Show(this.GetLocalizedString("ErrorWhileAddingAdmx"));
                            break;
                    }
                    if (newAdmx != null)
                    {
                        this.CurrentProject.SetAdmx(newAdmx);
                        this.AddAdmxTotreeview(newAdmx);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(this.GetLocalizedString("ErrorWhileAddingAdmx") + "\r\n" + ex.Message);
            }
        }

        private void AddCategoryToTreeview(AdmxProject project, Category category)
        {
            TreeNode newNode = new TreeNode(category.DisplayName, 2, 2);
            newNode.Tag = category;
            //project.Admx.OwnerNode.Nodes.Add(newNode);
            //category.Owner = project;
            //category.OwnerNode = newNode;
        }

        private void AddCategoryToTreeview(Category parentCategory, Category childCategory)
        {
            TreeNode newNode = new TreeNode(childCategory.DisplayName, 2, 2);
            newNode.Tag = childCategory;
            //parentCategory.OwnerNode.Nodes.Add(newNode);
            //childCategory.Owner = this.CurrentProject;
            //childCategory.OwnerNode = newNode;
        }

        /// <summary>
        /// Ask the user for the new name of the project.
        /// </summary>
        private void RenameProject()
        {
            try
            {
                FrmInputBox inputBox = new FrmInputBox();

                inputBox.Title = this.GetLocalizedString("Rename");
                inputBox.Description = this.GetLocalizedString("WhatIsTheNewName");
                inputBox.FilteredTextbox.AllowedCharacters.AddRange(Utilities.GetAllowedCharacters());
                inputBox.FilteredTextbox.AllowedCharacters.Add('_');
                inputBox.FilteredTextbox.AllowedCharacters.Add('-');
                inputBox.FilteredTextbox.AllowedCharacters.Add(' ');

                if (inputBox.ShowDialog() == System.Windows.Forms.DialogResult.OK && !String.IsNullOrEmpty(inputBox.UserInput))
                {
                    if (System.IO.File.Exists(System.IO.Path.Combine(this.CurrentProject.ProjectFolder, this.CurrentProject.ProjectName, inputBox.UserInput + ".AdmxProj")))
                    {
                        MessageBox.Show(this.GetLocalizedString("ThereIsAlreadyAProjectWithThisName"));
                    }
                    else
                    {
                        System.IO.FileInfo currentProjectFile = new System.IO.FileInfo(System.IO.Path.Combine(this.CurrentProject.ProjectFolder, this.CurrentProject.ProjectName, this.CurrentProject.ProjectName + ".AdmxProj"));
                        if (currentProjectFile.Exists)
                        {
                            try
                            {
                                currentProjectFile.MoveTo(System.IO.Path.Combine(currentProjectFile.DirectoryName, inputBox.UserInput + ".AdmxProj"));
                            }
                            catch (Exception ex) { MessageBox.Show(this.GetLocalizedString("AnErrorOccurredWhileRenamingTheFile") + "\r\n" + ex.Message, String.Empty, MessageBoxButtons.OK, MessageBoxIcon.Error); }
                        }
                        this.CurrentProject.ProjectName = inputBox.UserInput;
                        this.DisplayUIForProject();
                    }
                }
            }
            catch (Exception ex) { MessageBox.Show(this.GetLocalizedString("CannotRenameProject") + "\r\n" + ex.Message, String.Empty, MessageBoxButtons.OK, MessageBoxIcon.Error); }
        }

        /// <summary>
        /// Save the selected project or, all opened projects, if the Shift key is pressed.
        /// </summary>
        private void SaveProject()
        {
            try
            {
                if (ModifierKeys == Keys.Shift)
                {
                    foreach (AdmxProject project in this.OpenedProjects)
                    {
                        this.SaveProject(project);
                    }
                }
                else
                    this.SaveProject(this.CurrentProject);
            }
            catch (Exception ex) { MessageBox.Show(this.GetLocalizedString("CannotSaveProject") + "\r\n" + ex.Message, String.Empty, MessageBoxButtons.OK, MessageBoxIcon.Error); }
        }

        /// <summary>
        /// Close the selected project or, all opened projects, if the shift key is pressed.
        /// </summary>
        private void CloseProject()
        {
            try
            {
                if (ModifierKeys == Keys.Shift)
                {
                    if (MessageBox.Show(this.GetLocalizedString("AreYouSurToWantToCloseAllProjects"), String.Empty, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
                    {
                        this.CloseAllProjects();
                    }
                }
                else
                {
                    if (MessageBox.Show(this.GetLocalizedString("AreYouSurToWantToCloseTheProject"), String.Empty, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
                        this.CloseProject(this.CurrentProject);
                }
            }
            catch (Exception ex) { MessageBox.Show(this.GetLocalizedString("AnErrorOccurredWhileClosingProject") + "\r\n" + ex.Message, String.Empty, MessageBoxButtons.OK, MessageBoxIcon.Error); }
        }

        private void CloseAllProjects()
        {
            AdmxProject[] allProjects = this.OpenedProjects.ToArray();

            for (int i = 0; i < allProjects.Length; i++)
            {
                this.CloseProject(allProjects[i]);
            }
        }

        /// <summary>
        /// Save the current Project
        /// </summary>
        /// <param name="projectToSave">A reference to the project to save</param>
        private void SaveProject(AdmxProject projectToSave)
        {
            projectToSave.Save();
            this.AddRecentFile(System.IO.Path.Combine(projectToSave.ProjectFolder, projectToSave.ProjectName + ".AdmxProj"));
        }

        /// <summary>
        /// Close the current Project
        /// </summary>
        /// <param name="projectToClose">A reference to the project to close</param>
        private void CloseProject(AdmxProject projectToClose)
        {
            if (projectToClose.HaveUnsavedModifications && projectToClose.HasAdmx && MessageBox.Show(this.GetLocalizedString("DoYouWantToSaveModifications"), projectToClose.ProjectName, MessageBoxButtons.YesNo) == System.Windows.Forms.DialogResult.Yes)
            {
                try
                {
                    this.SaveProject(projectToClose);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(this.GetLocalizedString("CannotSaveProject") + "\r\n" + ex.Message, String.Empty, MessageBoxButtons.OK, MessageBoxIcon.Error);
                    if (MessageBox.Show(this.GetLocalizedString("CloseTheProjectAnyway"), String.Empty, MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2) == System.Windows.Forms.DialogResult.No)
                        return;
                }
            }
            this.OpenedProjects.Remove(projectToClose);
            //this.trvProjects.Nodes.Remove(projectToClose.OwnerNode);

            if (this.OpenedProjects.Count == 0)
            {
                this.CurrentProject = null;
                this.DisplayUIForNoSelection();
            }
        }

        /// <summary>
        /// Rename the Admx file.
        /// </summary>
        private void RenameAdmxFile()
        {
            try
            {
                System.IO.FileInfo currentFile = new System.IO.FileInfo(System.IO.Path.Combine(this.CurrentProject.ProjectFolder, this.CurrentProject.Admx.Filename + ".admx"));
                if (!currentFile.Exists)
                {
                    this.SaveProject(this.CurrentProject);
                }
                SaveFileDialog saveFileDlg = new SaveFileDialog();
                saveFileDlg.Filter = "Admx|*.admx";
                saveFileDlg.FileName = currentFile.Name;
                saveFileDlg.InitialDirectory = currentFile.DirectoryName;

                if (saveFileDlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    currentFile.MoveTo(saveFileDlg.FileName);
                    this.CurrentProject.RenameAdmx(System.IO.Path.GetFileNameWithoutExtension(saveFileDlg.FileName));
                    //this.CurrentProject.Admx.OwnerNode.Text = this.CurrentProject.Admx.Filename;
                }
            }
            catch (Exception ex) { MessageBox.Show(this.GetLocalizedString("CannotRenameAdmx") + "\r\n" + ex.Message, String.Empty, MessageBoxButtons.OK, MessageBoxIcon.Error); }
        }

        /// <summary>
        /// Remove the current Admx from the project
        /// </summary>
        private void DeleteAdmxFile()
        {
            try
            {
                if (MessageBox.Show(this.GetLocalizedString("AreYouSureToDeleteAdmx") + "\r\n" + this.CurrentProject.Admx.Filename, this.GetLocalizedString("DeleteAdmx"), MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2) == System.Windows.Forms.DialogResult.Yes)
                {
                    //TreeNode admxNode = this.CurrentProject.Admx.OwnerNode;
                    //this.trvProjects.SelectedNode = this.CurrentProject.OwnerNode;
                    //this.CurrentProject.DeleteAdmx();
                    //this.CurrentProject.OwnerNode.Nodes.Remove(admxNode);
                    //this.DisplayUIForProject();
                }
            }
            catch (Exception ex) { MessageBox.Show(this.GetLocalizedString("CannotRemoveAdmx") + "\r\n" + ex.Message, String.Empty, MessageBoxButtons.OK, MessageBoxIcon.Error); }
        }

        /// <summary>
        /// Add a language to the current project
        /// </summary>
        private void AddLanguage()
        {
            try
            {
                FrmAddLanguage addLanguage = new FrmAddLanguage(this.CurrentProject.GetAdmlList());

                if (addLanguage.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    this.CurrentProject.AddAdml(new AdmlFile((addLanguage.SelectedCulture.CultureInfo.Name)));
                    this.DisplayProjectLanguages();
                }
            }
            catch (Exception ex) { MessageBox.Show(this.GetLocalizedString("AnErrorOccuredWhileAddingLanguage") + "\r\n" + ex.Message, String.Empty, MessageBoxButtons.OK, MessageBoxIcon.Error); }
        }

        /// <summary>
        /// Delete the currently selected language
        /// </summary>
        private void DeleteCurrentLanguage()
        {
            try
            {
                if (this.CurrentLanguage != null)
                {
                    if (MessageBox.Show(this.GetLocalizedString("AreYouSureYouWantToDeleteCurrentLanguage") + this.CurrentLanguage.Culture.DisplayName + " ?", String.Empty, MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == System.Windows.Forms.DialogResult.Yes)
                    {
                        this.CurrentProject.RemoveAdml(this.CurrentLanguage);
                        this.CurrentLanguage = this.CurrentProject.Admx.Resources.FallbackCulture;
                        this.txtBxFallbackCulture_Click(null, null);
                        this.txtBxFallbackCulture.Focus();
                        this.RefreshUILanguage();
                        this.ribBtnDeleteLanguage.Enabled = false;
                        this.DisplayProjectLanguages();
                    }
                }
            }
            catch (Exception ex) { MessageBox.Show(this.GetLocalizedString("AnErrorOccuredWhileDeletingLanguage") + "\r\n" + ex.Message, String.Empty, MessageBoxButtons.OK, MessageBoxIcon.Error); }
        }

        /// <summary>
        /// Add the full path on top of the RecentFile list if it doesn't exists
        /// </summary>
        /// <param name="fullpath">the full path to the file to add</param>
        private void AddRecentFile(string fullpath)
        {
            try
            {
                System.IO.FileInfo fileToAdd = new System.IO.FileInfo(fullpath);
                this._mru.AddItem(new MruItem(fileToAdd.DirectoryName, fileToAdd.Name));
                this.DisplayRecentelyOpenedFiles();
            }
            catch (Exception) { }
        }

        /// <summary>
        /// Fill the MruList with the list of recentely opened files stored in the Settings of the application.
        /// </summary>
        private void InitializeMRU()
        {
            this._mru.Clear();

            for (int i = 0; i < 10; i++)
            {
                try
                {
                    System.IO.FileInfo recentelyOpenedFile = new System.IO.FileInfo(Properties.Settings.Default[String.Concat("RecentFile", i)].ToString());
                    bool isPinned = Convert.ToBoolean(Properties.Settings.Default[String.Concat("IsPinned", i)]);

                    if (recentelyOpenedFile.Exists)
                    {
                        MruItem mruItem = new MruItem(recentelyOpenedFile.DirectoryName, recentelyOpenedFile.Name, isPinned);
                        mruItem.Tag = i;
                        this._mru.AddItem(mruItem);
                    }
                }
                catch (Exception) { }
            }
        }

        /// <summary>
        /// Clear all recentely opened files from the Orb Menu and populate it again with the Mru List
        /// </summary>
        private void DisplayRecentelyOpenedFiles()
        {
            this.ribMain.OrbDropDown.RecentItems.Clear();
            foreach (MruItem item in this._mru.GetItems())
            {
                this.DisplayRecentOpenedFile(item);
            }
        }

        /// <summary>
        /// Check if the file exists and add it to the 'RecentItems' in the OrbDropDown Menu. If the file doesn't exists, no items are added.
        /// </summary>
        /// <param name="fullPath">Full path to the file</param>
        private void DisplayRecentOpenedFile(MruItem mruItem)
        {
            try
            {
                RibbonButton item = new RibbonButton(mruItem.Filename);
                item.SmallImage = mruItem.IsPinned ? Properties.Resources.Pinned16x16 : this._blankImage;
                item.Tag = mruItem;
                this.ribMain.OrbDropDown.RecentItems.Add(item);
                item.Click += new EventHandler(recentFile_Click);
            }
            catch (Exception) { }
        }

        /// <summary>
        /// Update application properties with the Mru list
        /// </summary>
        private void UpdatePropertiesWithMruList()
        {
            int i = 0;
            foreach (MruItem item in this._mru.GetItems())
            {
                try
                {
                    Properties.Settings.Default[String.Concat("RecentFile", i.ToString())] = System.IO.Path.Combine(item.Folder, item.Filename);
                    Properties.Settings.Default[String.Concat("IsPinned", i.ToString())] = item.IsPinned;
                    i++;
                }
                catch (Exception) { }
            }
            Properties.Settings.Default.Save();
        }

        private void Quit()
        {
            this.Close();
        }

        private void LoadAdmxFile(string filename)
        {
            MessageBox.Show("Will Load : " + filename);
        }

        /// <summary>
        /// Rename the selected Category
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void RenameCategory(object sender, EventArgs e)
        {
            try
            {
                TreeNode selectedNode = this.trvProjects.SelectedNode;

                if (selectedNode != null && selectedNode.Tag != null && selectedNode.Tag.GetType() == typeof(Category))
                {
                    Category categoryToRename = (Category)selectedNode.Tag;
                    //selectedNode.Text = categoryToRename.Rename();
                }

            }
            catch (Exception) { }
        }

        /// <summary>
        /// Delete the selected Category.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DeleteCategory(object sender, EventArgs e)
        {
            try
            {
                TreeNode selectedNode = this.trvProjects.SelectedNode;

                if (selectedNode != null && selectedNode.Tag != null && selectedNode.Tag.GetType() == typeof(Category))
                {
                    if (MessageBox.Show(this.GetLocalizedString("DoYouReallyWantToDeleteThisCategory"), "", MessageBoxButtons.YesNo) == System.Windows.Forms.DialogResult.Yes)
                    {
                        Category categoryToDelete = (Category)selectedNode.Tag;
                        this.trvProjects.Nodes.Remove(selectedNode);
                        //this.CurrentProject.RemoveCategory(categoryToDelete);
                    }
                }
            }
            catch (Exception) { }
        }

        /// <summary>
        /// Returns a localized string depending of the current culture.
        /// </summary>
        /// <param name="unlocalizedString">string to localized.</param>
        /// <returns>the localized string.</returns>
        protected string GetLocalizedString(string unlocalizedString)
        {
            string result = string.Empty;

            try
            {
                result = resMan.GetString(unlocalizedString);
                if (!string.IsNullOrEmpty(result))
                    return result;
            }
            catch (Exception) { }

            return "Missing_Localized_String_For(" + ((unlocalizedString != null) ? unlocalizedString : "null") + ")";
        }

        #endregion (Private Methods)

        #region (UI Managment)

        // Boutons ADMX Ruban 
        private void ribOrbQuit_Click(object sender, EventArgs e)
        {
            this.Quit();
        }

        private void ribOrbNewProject_Click(object sender, EventArgs e)
        {
            this.NewProject();
        }

        private void ribOrbSaveAs_Click(object sender, EventArgs e)
        {
        }

        private void ribOrbOptions_Click(object sender, EventArgs e)
        {
            FrmOptions frmOptions = new FrmOptions();

            frmOptions.ShowDialog();
        }

        private void ribBtnOpenProject_Click(object sender, EventArgs e)
        {

        }

        private void ribBtnAddAdmx_Click(object sender, EventArgs e)
        {
            this.AddAdmxToProject();
        }

        private void ribBtnRenameAdmx_Click(object sender, EventArgs e)
        {
            this.RenameAdmxFile();
        }

        private void ribBtnDeleteAdmx_Click(object sender, EventArgs e)
        {
            this.DeleteAdmxFile();
        }

        private void ribBtnAddCategory_Click(object sender, EventArgs e)
        {
            if (this.trvProjects.SelectedNode != null && this.trvProjects.SelectedNode.Tag != null)
            {
                Type tagType = this.trvProjects.SelectedNode.Tag.GetType();
                if (tagType == typeof(AdmxFile) || tagType == typeof(Category))
                {
                    FrmAddCategory frmAddCategory = new FrmAddCategory(this.CurrentLanguage, this.CurrentProject.Admx.Resources.FallbackCulture, tagType == typeof(AdmxFile));
                    frmAddCategory.PopulateWithWindowsNamespace();
                    if (frmAddCategory.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                    {
                        foreach (Category category in frmAddCategory.Categories)
                        {
                            //if (!this.CurrentProject.CategoryExists(category))
                            //{
                            //    this.CurrentProject.AddCategory(category);
                            //    if (tagType == typeof(AdmxFile))
                            //    {
                            //        this.AddCategoryToTreeview(this.CurrentProject, category);
                            //    }
                            //    if (tagType == typeof(Category))
                            //    {
                            //        Category parentCategory = (Category)this.trvProjects.SelectedNode.Tag;
                            //        Namespace windowsNamespace = new Namespace(@"%WinDir%\PolicyDefinitions\Windows.admx");
                            //        category.ParentCategory = new Reference(windowsNamespace.Prefix, parentCategory.Name);
                            //        this.AddCategoryToTreeview(parentCategory, category);
                            //    }
                            //}
                            //else
                            //{
                            //    MessageBox.Show(this.GetLocalizedString("CannotAddCategoryThatDoesExists") + "\r\n" + category.Name);
                            //}
                        }
                        this.trvProjects.SelectedNode.Expand();
                    }
                }
            }
        }

        // Boutons ADML ruban
        private void ribBtnAddLanguage_Click(object sender, EventArgs e)
        {
            this.AddLanguage();
        }

        private void ribBtnDeleteLanguage_Click(object sender, EventArgs e)
        {
            this.DeleteCurrentLanguage();
        }

        // Items du menu contextuel Projet
        private void renameProject_Click(object sender, EventArgs e)
        {
            this.RenameProject();
        }

        private void saveProject_Click(object sender, EventArgs e)
        {
            SaveProject();
        }

        private void closeProject_Click(object sender, EventArgs e)
        {
            CloseProject();
        }

        /// <summary>
        /// This event is fire when the user click on a button in the Recentely Opened Admx Files list.
        /// </summary>
        /// <param name="sender">Button that have been click.</param>
        /// <param name="e"></param>
        private void recentFile_Click(object sender, EventArgs e)
        {
            MouseEventArgs mouseEvent = (MouseEventArgs)e;
            RibbonButton ribButton = (RibbonButton)sender;

            if (mouseEvent.Button == System.Windows.Forms.MouseButtons.Right)
            {
                try
                {
                    MruItem clickedItem = (MruItem)ribButton.Tag;
                    clickedItem.IsPinned = !clickedItem.IsPinned;
                    ribButton.SmallImage = clickedItem.IsPinned ? Properties.Resources.Pinned16x16 : this._blankImage;
                }
                catch (Exception) { }
            }
            else if (mouseEvent.Button == System.Windows.Forms.MouseButtons.Left)
            {
                try
                {
                    MruItem item = (MruItem)ribButton.Tag;
                    this.LoadAdmxFile(System.IO.Path.Combine(item.Folder, item.Filename));
                }
                catch (Exception) { }
            }
        }

        // Treeview Projet
        private void trvProjets_AfterSelect(object sender, TreeViewEventArgs e)
        {
            SetUIAfterNodeSelected();
        }

        private void trvProjects_Click(object sender, EventArgs e)
        {
            MouseEventArgs mouseEvent = (MouseEventArgs)e;


            TreeNode clickedNode = this.trvProjects.GetNodeAt(mouseEvent.Location);
            if (clickedNode != null)
                this.trvProjects.SelectedNode = clickedNode;

            if (mouseEvent.Button == System.Windows.Forms.MouseButtons.Right)
            {
                Type nodeType = clickedNode.Tag.GetType();

                if (nodeType == typeof(AdmxProject))
                {
                    this.ctxMnuProject.Items[0].Enabled = !this.CurrentProject.HasAdmx;
                    this.ctxMnuProject.Show(this.trvProjects, this.trvProjects.PointToClient(Cursor.Position));
                }
                else if (nodeType == typeof(AdmxFile))
                {
                    this.ctxMnuAdmx.Show(this.trvProjects, this.trvProjects.PointToClient(Cursor.Position));
                }
                else if (nodeType == typeof(Category))
                {
                    this.ctxMnuCategory.Show(this.trvProjects, this.trvProjects.PointToClient(Cursor.Position));
                }
                else if (nodeType == typeof(Policy))
                {
                    this.ctxMnuPolicy.Show(this.trvProjects, this.trvProjects.PointToClient(Cursor.Position));
                }
            }
        }

        // TextBox Fallback Culture
        private void txtBxFallbackCulture_Click(object sender, EventArgs e)
        {
            if (this.CurrentProject != null && this.CurrentProject.HasAdmx)
            {
                this.lstBxAdml.SelectedIndex = -1;
                this.txtBxFallbackCulture.BackColor = SystemColors.Highlight;
                this.txtBxFallbackCulture.ForeColor = SystemColors.HighlightText;
                this.CurrentLanguage = this.CurrentProject.Admx.Resources.FallbackCulture;
                this.RefreshUILanguage();
            }
        }

        // ListBox Languages
        private void lstBxAdml_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                if (this.lstBxAdml.SelectedItem != null)
                {
                    this.ribBtnDeleteLanguage.Enabled = true;
                    this.txtBxFallbackCulture.BackColor = SystemColors.Control;
                    this.txtBxFallbackCulture.ForeColor = SystemColors.ControlText;
                    AdmlFile selectedLanguage = (AdmlFile)this.lstBxAdml.SelectedItem;
                    this.CurrentLanguage = selectedLanguage;
                    this.RefreshUILanguage();
                }
                else
                    this.ribBtnDeleteLanguage.Enabled = false;
            }
            catch (Exception) { }
        }

        private void lstBxAdml_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Delete && e.Modifiers == Keys.Shift)
            {
                this.DeleteCurrentLanguage();
            }
        }

        private void SetUIAfterNodeSelected()
        {
            this.Cursor = Cursors.WaitCursor;
            if (this.trvProjects.SelectedNode != null)
            {
                if (this.trvProjects.SelectedNode.Tag != null)
                {
                    Type objectType = this.trvProjects.SelectedNode.Tag.GetType();

                    if (objectType == typeof(ProjectViewer))
                    {
                        ProjectViewer viewer =  (ProjectViewer)this.trvProjects.SelectedNode.Tag;
                        this.CurrentProject = viewer.Project;
                        this.DisplayUIForProject();
                    }
                    if (objectType == typeof(AdmxFile))
                    {
                        this.CurrentProject = (AdmxProject)this.trvProjects.SelectedNode.Parent.Tag;
                        this.DisplayUIForAdmx();
                    }
                    if (objectType == typeof(Category))
                    {
                        Category selectedCategory = (Category)this.trvProjects.SelectedNode.Tag;
                        //this.CurrentProject = selectedCategory.Owner;
                        this.DisplayUIForCategory(selectedCategory);
                    }
                }
            }
            else
            {
                this.DisplayUIForNoSelection();
            }
            this.Cursor = Cursors.Default;
        }

        private void RefreshUILanguage()
        {
            if (this.splitContainer1.Panel2.Controls.Count == 1)
            {
                Control ctrl = this.splitContainer1.Panel2.Controls[0];
                Type ctrlType = ctrl.GetType();

                if (ctrlType == typeof(AdmxViewer))
                {

                }
                else if (ctrlType == typeof(CategoryViewer))
                {
                    CategoryViewer viewer = (CategoryViewer)ctrl;
                }
            }
        }

        private void DisplayUIForProject()
        {
            // Orb Menu
            this.ribOrbNewProject.Enabled = true;
            this.ribOrbOpenProject.Enabled = true;
            this.ribOrbCloseProject.Enabled = true;
            this.ribOrbSave.Enabled = true;
            this.ribOrbSaveAs.Enabled = true;

            // Project Panel
            this.ribBtnRenameProject.Enabled = true;
            this.ribBtnSaveProject.Enabled = true;
            this.ribBtnCloseProject.Enabled = true;

            // Admx Panel
            this.ribBtnAddAdmx.Enabled = !this.CurrentProject.HasAdmx;
            this.ribBtnAddCategory.Enabled = false;
            this.ribBtnRenameAdmx.Enabled = false;
            this.ribBtnDeleteAdmx.Enabled = false;

            // Category Panel
            this.ribBtnRenameCategory.Enabled = false;
            this.ribBtnDeleteCategory.Enabled = false;

            // Policy Panel
            this.ribBtnAddPolicy.Enabled = false;
            this.ribBtnRenamePolicy.Enabled = false;
            this.ribBtnDeletePolicy.Enabled = false;

            //Language Panel
            this.ribBtnAddLanguage.Enabled = this.CurrentProject.HasAdmx;

            this.splitContainer1.Panel2.Controls.Clear();
            ProjectViewer projectViewer = new ProjectViewer(this.CurrentProject);
            projectViewer.Dock = DockStyle.Fill;
            this.splitContainer1.Panel2.Controls.Add(projectViewer);
        }

        private void DisplayUIForAdmx()
        {
            // Orb Menu
            this.ribOrbNewProject.Enabled = true;
            this.ribOrbOpenProject.Enabled = true;
            this.ribOrbCloseProject.Enabled = true;
            this.ribOrbSave.Enabled = true;
            this.ribOrbSaveAs.Enabled = true;

            // Project Panel
            this.ribBtnRenameProject.Enabled = false;
            this.ribBtnSaveProject.Enabled = true;
            this.ribBtnCloseProject.Enabled = true;

            // Admx Panel
            this.ribBtnAddAdmx.Enabled = !this.CurrentProject.HasAdmx;
            this.ribBtnAddCategory.Enabled = true;
            this.ribBtnRenameAdmx.Enabled = true;
            this.ribBtnDeleteAdmx.Enabled = true;

            // Category Panel
            this.ribBtnRenameCategory.Enabled = false;
            this.ribBtnDeleteCategory.Enabled = false;

            // Policy Panel
            this.ribBtnAddPolicy.Enabled = false;
            this.ribBtnRenamePolicy.Enabled = false;
            this.ribBtnDeletePolicy.Enabled = false;

            //Language Panel
            this.ribBtnAddLanguage.Enabled = this.CurrentProject.HasAdmx;

            this.splitContainer1.Panel2.Controls.Clear();
            AdmxViewer admxViewer = new AdmxViewer(this.CurrentProject.Admx);
            admxViewer.Dock = DockStyle.Fill;
            this.splitContainer1.Panel2.Controls.Add(admxViewer);
            //admxViewer.PopulateFallbackCulture(this.CurrentProject.GetAdmlList());
        }

        private void DisplayUIForCategory(Category selectedCategory)
        {
            this.ribBtnRenameAdmx.Enabled = false;
            this.ribBtnAddPolicy.Enabled = true;
            this.ribBtnAddCategory.Enabled = true;
            this.ribBtnRenameCategory.Enabled = (selectedCategory.ParentCategory == null || String.IsNullOrEmpty(selectedCategory.ParentCategory.NamespacePrefix));
            this.ribBtnDeleteCategory.Enabled = true;
            this.ribBtnRenamePolicy.Enabled = false;
            this.ribBtnDeletePolicy.Enabled = false;

            this.splitContainer1.Panel2.Controls.Clear();
            CategoryViewer catViewer = new CategoryViewer(selectedCategory, this.CurrentLanguage);
            catViewer.Dock = DockStyle.Fill;
            this.splitContainer1.Panel2.Controls.Add(catViewer);
        }

        private void DisplayUIForPolicy(Policy selectedPolicy)
        {

            this.ribBtnAddCategory.Enabled = false;
            this.ribBtnRenameAdmx.Enabled = false;
            this.ribBtnAddPolicy.Enabled = false;
            this.ribBtnRenameCategory.Enabled = false;
            this.ribBtnDeleteCategory.Enabled = false;
            this.ribBtnRenamePolicy.Enabled = true;
            this.ribBtnDeletePolicy.Enabled = true;

            this.splitContainer1.Panel2.Controls.Clear();
        }

        private void DisplayUIForNoSelection()
        {
            // Orb Menu
            this.ribOrbNewProject.Enabled = true;
            this.ribOrbOpenProject.Enabled = true;
            this.ribOrbCloseProject.Enabled = false;
            this.ribOrbSave.Enabled = false;
            this.ribOrbSaveAs.Enabled = false;

            // Project Panel
            this.ribBtnAddAdmx.Enabled = (this.CurrentProject == null || this.CurrentProject.HasAdmx);
            this.ribBtnRenameProject.Enabled = false;
            this.ribBtnSaveProject.Enabled = false;
            this.ribBtnCloseProject.Enabled = false;

            // Admx Panel
            this.ribBtnAddAdmx.Enabled = false;
            this.ribBtnAddCategory.Enabled = false;
            this.ribBtnRenameAdmx.Enabled = false;
            this.ribBtnDeleteAdmx.Enabled = false;

            // Category Panel
            this.ribBtnAddPolicy.Enabled = false;
            this.ribBtnRenameCategory.Enabled = false;
            this.ribBtnDeleteCategory.Enabled = false;

            // Policy Panel
            this.ribBtnRenamePolicy.Enabled = false;
            this.ribBtnDeletePolicy.Enabled = false;

            this.splitContainer1.Panel2.Controls.Clear();
            this.lstBxAdml.Items.Clear();
        }

        private void ribBtnAddPolicy_Click(object sender, EventArgs e)
        {

        }

        private void ContextMenuItem_Click(object sender, EventArgs e)
        {
            if (sender.GetType() == typeof(ToolStripMenuItem))
            {
                ToolStripMenuItem clickedItem = (ToolStripMenuItem)sender;

                switch (clickedItem.Name)
                {
                    // Project
                    case "AddAdmxToolStripMenuItem":
                        this.AddAdmxToProject();
                        break;
                    case "RenameProjectToolStripMenuItem":
                        this.RenameProject();
                        break;
                    case "SaveProjectToolStripMenuItem":
                        this.SaveProject();
                        break;
                    case "CloseProjectToolStripMenuItem":
                        this.CloseProject();
                        break;
                    // Admx
                    case "RenameAdmxToolStripMenuItem":
                        this.RenameAdmxFile();
                        break;
                    case "RemoveAdmxToolStripMenuItem":
                        this.DeleteAdmxFile();
                        break;

                    // Category

                    // Policy

                }
            }
        }

        private void CurrentProject_HasUnsavedModificationsChanged(AdmxProject sender)
        {
            //TreeNode ownerNode = sender.OwnerNode;
            //ownerNode.Text = sender.HaveUnsavedModifications ? sender.ProjectName + "*" : sender.ProjectName;

            if (this.splitContainer1.Panel2.Controls.Count == 1)
            {
                Type ctrlType = this.splitContainer1.Panel2.Controls[0].GetType();

                if (ctrlType == typeof(AdmxViewer))
                {
                    AdmxViewer viewer = (AdmxViewer)this.splitContainer1.Panel2.Controls[0];
                    viewer.UpdateDisplay();
                }
            }
            this.DisplayProjectLanguages();
        }

        // Main Form
        private void frmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            this.UpdatePropertiesWithMruList();
            this.CloseAllProjects();
        }

        #endregion (UI Managment)
    }
}
